package mqtt

import (
    "bufio"
    "fmt"
    "io"
    
    "github.com/yangyongzhen/mqtt-broker/internal/protocol/common"
    "github.com/yangyongzhen/mqtt-broker/internal/protocol/mqtt311"
)

type PacketReader struct {
    reader *bufio.Reader
}

func NewPacketReader(r io.Reader) *PacketReader {
    return &PacketReader{
        reader: bufio.NewReader(r),
    }
}

func (pr *PacketReader) ReadPacket() (common.Packet, error) {
    // 读取固定头部第一个字节
    firstByte, err := pr.reader.ReadByte()
    if err != nil {
        return nil, err
    }
    
    // 解析消息类型和标志
    messageType := common.MessageType((firstByte >> 4) & 0x0F)
    dup := (firstByte & 0x08) != 0
    qos := common.QoS((firstByte >> 1) & 0x03)
    retain := (firstByte & 0x01) != 0
    
    // 读取剩余长度
    remainingLength, err := pr.readRemainingLength()
    if err != nil {
        return nil, err
    }
    
    // 读取数据包内容
    data := make([]byte, remainingLength)
    if remainingLength > 0 {
        _, err = io.ReadFull(pr.reader, data)
        if err != nil {
            return nil, err
        }
    }
    
    // 创建对应的数据包
    var packet common.Packet
    
    switch messageType {
    case common.CONNECT:
        packet = &mqtt311.ConnectPacket{}
    case common.CONNACK:
        packet = &mqtt311.ConnackPacket{}
    case common.PUBLISH:
        publishPacket := &mqtt311.PublishPacket{}
        publishPacket.FixedHeader.DUP = dup
        publishPacket.FixedHeader.QoS = qos
        publishPacket.FixedHeader.Retain = retain
        packet = publishPacket
    case common.SUBSCRIBE:
        packet = &mqtt311.SubscribePacket{}
    case common.SUBACK:
        packet = &mqtt311.SubackPacket{}
    case common.PINGREQ:
        return &PingReqPacket{}, nil
    case common.PINGRESP:
        return &PingRespPacket{}, nil
    case common.DISCONNECT:
        return &DisconnectPacket{}, nil
    default:
        return nil, fmt.Errorf("unsupported message type: %d", messageType)
    }
    
    // 解码数据包
    if len(data) > 0 {
        err = packet.Decode(data)
        if err != nil {
            return nil, err
        }
    }
    
    return packet, nil
}

func (pr *PacketReader) readRemainingLength() (uint32, error) {
    var length uint32
    var multiplier uint32 = 1
    
    for {
        encodedByte, err := pr.reader.ReadByte()
        if err != nil {
            return 0, err
        }
        
        length += uint32(encodedByte&127) * multiplier
        if (encodedByte & 128) == 0 {
            break
        }
        multiplier *= 128
        if multiplier > 128*128*128 {
            return 0, fmt.Errorf("remaining length exceeds maximum")
        }
    }
    
    return length, nil
}

// 简单数据包类型
type PingReqPacket struct{}

func (p *PingReqPacket) Type() common.MessageType { return common.PINGREQ }
func (p *PingReqPacket) Encode() ([]byte, error)  { return []byte{0xC0, 0x00}, nil }
func (p *PingReqPacket) Decode([]byte) error      { return nil }

type PingRespPacket struct{}

func (p *PingRespPacket) Type() common.MessageType { return common.PINGRESP }
func (p *PingRespPacket) Encode() ([]byte, error)  { return []byte{0xD0, 0x00}, nil }
func (p *PingRespPacket) Decode([]byte) error      { return nil }

type DisconnectPacket struct{}

func (p *DisconnectPacket) Type() common.MessageType { return common.DISCONNECT }
func (p *DisconnectPacket) Encode() ([]byte, error)  { return []byte{0xE0, 0x00}, nil }
func (p *DisconnectPacket) Decode([]byte) error      { return nil }
